package com.aizuda.boot.modules.business.mobile.service.impl;

import com.aizuda.boot.modules.business.approval.entity.dto.TaskCenterQueryDTO;
import com.aizuda.boot.modules.business.approval.entity.vo.PendingApprovalTaskVO;
import com.aizuda.boot.modules.business.approval.service.TaskCenterService;
import com.aizuda.boot.modules.business.mobile.entity.vo.MobileStatisticsVO;
import com.aizuda.boot.modules.business.mobile.entity.vo.MyContractCountVO;
import com.aizuda.boot.modules.business.mobile.entity.vo.MyReminderCountVO;
import com.aizuda.boot.modules.business.mobile.service.MobileService;
import com.aizuda.boot.modules.business.negotiation.entity.dto.NegotiationListReqDTO;
import com.aizuda.boot.modules.business.negotiation.entity.vo.NegotiationListRespDTO;
import com.aizuda.boot.modules.business.negotiation.service.ContractNegotiationService;
import com.aizuda.boot.modules.business.contract.mapper.ContractMapper;
import com.aizuda.boot.modules.business.contract.mapper.ContractFieldMapper;
import com.aizuda.boot.modules.business.contract.mapper.ContractFieldValueMapper;
import com.aizuda.boot.modules.business.contract.entity.ContractEntity;
import com.aizuda.boot.modules.business.contract.util.AuthUtil;
import com.aizuda.boot.modules.common.constant.enums.ContractStatusEnum;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * Mobile端服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MobileServiceImpl implements MobileService {

    private final TaskCenterService taskCenterService;
    private final ContractNegotiationService contractNegotiationService;
    private final ContractMapper contractMapper;
    private final ContractFieldMapper contractFieldMapper;
    private final ContractFieldValueMapper contractFieldValueMapper;

    @Override
    public MobileStatisticsVO getStatistics(Long userId) {
        log.info("开始获取用户 {} 的Mobile端统计数据", userId);

        try {
            // 1. 获取我的待办总数
            Long pendingCount = getPendingCount(userId);
            log.info("用户 {} 的待办总数: {}", userId, pendingCount);

            // 2. 获取抄送我的总数
            Long ccCount = getCcCount(userId);
            log.info("用户 {} 的抄送总数: {}", userId, ccCount);

            // 3. 获取待我协商总数
            Long negotiationCount = getNegotiationCount(userId);
            log.info("用户 {} 的协商总数: {}", userId, negotiationCount);

            MobileStatisticsVO result = MobileStatisticsVO.builder()
                    .pendingCount(pendingCount)
                    .ccCount(ccCount)
                    .negotiationCount(negotiationCount)
                    .build();

            log.info("用户 {} 的Mobile端统计数据获取完成: {}", userId, result);
            return result;

        } catch (Exception e) {
            log.error("获取用户 {} 的Mobile端统计数据失败", userId, e);
            // 返回默认值，避免接口报错
            return MobileStatisticsVO.builder()
                    .pendingCount(0L)
                    .ccCount(0L)
                    .negotiationCount(0L)
                    .build();
        }
    }

    @Override
    public MyContractCountVO getMyContractCount(Long userId) {
        log.info("开始获取用户 {} 的合同统计数据", userId);

        try {
            // 根据合同状态统计数量
            // 审批中的合同
            Long approvingCount = getContractCountByStatus(userId, ContractStatusEnum.IN_APPROVAL.getCode());
            
            // 已盖章的合同
            Long sealedCount = getContractCountByStatus(userId, ContractStatusEnum.SEALED.getCode());
            
            // 已归档的合同
            Long archivedCount = getContractCountByStatus(userId, ContractStatusEnum.ARCHIVED.getCode());

            MyContractCountVO result = MyContractCountVO.builder()
                    .approvingCount(approvingCount)
                    .sealedCount(sealedCount)
                    .archivedCount(archivedCount)
                    .build();

            log.info("用户 {} 的合同统计数据获取完成: {}", userId, result);
            return result;

        } catch (Exception e) {
            log.error("获取用户 {} 的合同统计数据失败", userId, e);
            return MyContractCountVO.builder()
                    .approvingCount(0L)
                    .sealedCount(0L)
                    .archivedCount(0L)
                    .build();
        }
    }

    @Override
    public MyReminderCountVO getMyReminderCount(Long userId) {
        log.info("开始获取用户 {} 的提醒统计数据", userId);

        try {
            LocalDate today = LocalDate.now();
            LocalDate thirtyDaysLater = today.plusDays(30);

            // 获取30天内到期的合同总数
            Long expiringSoonCount = getExpiringContractCount(userId, today, thirtyDaysLater);
            
            // 获取今天到期的合同总数
            Long expiringTodayCount = getExpiringContractCount(userId, today, today.plusDays(1));

            MyReminderCountVO result = MyReminderCountVO.builder()
                    .expiringSoonCount(expiringSoonCount)
                    .expiringTodayCount(expiringTodayCount)
                    .build();

            log.info("用户 {} 的提醒统计数据获取完成: {}", userId, result);
            return result;

        } catch (Exception e) {
            log.error("获取用户 {} 的提醒统计数据失败", userId, e);
            return MyReminderCountVO.builder()
                    .expiringSoonCount(0L)
                    .expiringTodayCount(0L)
                    .build();
        }
    }

    /**
     * 获取我的待办总数
     */
    private Long getPendingCount(Long userId) {
        try {
            TaskCenterQueryDTO queryDTO = new TaskCenterQueryDTO();
            queryDTO.setCurrent(1L);
            queryDTO.setSize(1L); // 只需要获取总数，不需要具体数据
            
            // 使用优化版本的方法，确保与taskcenter/pending接口数据一致
            Page<PendingApprovalTaskVO> page = taskCenterService.getPendingApprovalTasksOptimized(queryDTO, userId);
            return page.getTotal();

        } catch (Exception e) {
            log.error("获取用户 {} 的待办总数失败", userId, e);
            return 0L;
        }
    }

    /**
     * 获取抄送我的总数
     */
    private Long getCcCount(Long userId) {
        try {
            TaskCenterQueryDTO queryDTO = new TaskCenterQueryDTO();
            queryDTO.setCurrent(1L);
            queryDTO.setSize(1L); // 只需要获取总数，不需要具体数据
            
            // 使用优化版本的方法，确保与taskcenter/cc接口数据一致
            Page<PendingApprovalTaskVO> page = taskCenterService.getCcTasksOptimized(queryDTO, userId);
            return page.getTotal();

        } catch (Exception e) {
            log.error("获取用户 {} 的抄送总数失败", userId, e);
            return 0L;
        }
    }

    /**
     * 获取待我协商总数
     */
    private Long getNegotiationCount(Long userId) {
        try {
            NegotiationListReqDTO reqDTO = new NegotiationListReqDTO();
            reqDTO.setPageNum(1);
            reqDTO.setPageSize(1); // 只需要获取总数，不需要具体数据
            reqDTO.setFilterType("PENDING_MY_CONFIRM"); // 待我确认的协商
            
            Page<NegotiationListRespDTO> page = contractNegotiationService.getNegotiationList(reqDTO);
            return page.getTotal();

        } catch (Exception e) {
            log.error("获取用户 {} 的协商总数失败", userId, e);
            return 0L;
        }
    }

    /**
     * 根据合同状态统计合同数量
     */
    private Long getContractCountByStatus(Long userId, String status) {
        try {
            // 获取申请人字段ID（用于关联查询用户的合同）
            Long applyPeopleFieldId = getApplyPeopleFieldId();
            if (applyPeopleFieldId == null) {
                log.warn("未找到申请人字段ID");
                return 0L;
            }
            
            // 使用现有的查询方法，queryType=1表示查询我的合同
            List<ContractEntity> contracts = contractMapper.selectContractsByQueryType(1, userId, applyPeopleFieldId);
            
            // 过滤指定状态的合同
            return contracts.stream()
                    .filter(contract -> status.equals(contract.getCurrentStatus()))
                    .count();
        } catch (Exception e) {
            log.error("查询用户 {} 状态为 {} 的合同数量失败", userId, status, e);
            return 0L;
        }
    }

    /**
     * 获取指定时间范围内到期的合同数量
     */
    private Long getExpiringContractCount(Long userId, LocalDate startDate, LocalDate endDate) {
        try {
            // 使用优化的查询方法，直接在数据库层面筛选到期合同
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String startDateStr = startDate.format(formatter);
            String endDateStr = endDate.format(formatter);
            
            // 获取用户的租户权限
            List<String> tenantKeys = AuthUtil.getUserTenantKeys();
            
            return contractMapper.selectExpiringContractCountOptimized(userId, tenantKeys, startDateStr, endDateStr);
        } catch (Exception e) {
            log.error("查询用户 {} 在 {} 到 {} 期间到期的合同数量失败", userId, startDate, endDate, e);
            return 0L;
        }
    }

    /**
     * 获取申请人字段ID
     */
    private Long getApplyPeopleFieldId() {
        try {
            return contractFieldMapper.selectList(null).stream()
                    .filter(field -> "apply_people".equals(field.getCode()))
                    .map(field -> field.getId())
                    .findFirst()
                    .orElse(null);
        } catch (Exception e) {
            log.error("获取申请人字段ID失败", e);
            return null;
        }
    }

}